package com.zspringboot.demo.controller;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zspringboot.demo.common.Result;
import com.zspringboot.demo.entity.IFile;
import com.zspringboot.demo.mapper.FileMapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;

/**
 * 文件上传相关接口
 * @program: springboot2
 * @description:
 * @author: LaoLang
 * @create: 2024-02-19 16:02
 * @version:1.0
 **/
@RestController
@RequestMapping("/file")
public class FileController {

    @Value("${files.upload.path}")
    private String fileUploadPath;

    
    @Resource
    private FileMapper fileMapper;
    /**
     * 文件上传接口
     * @param file 前端传递过来的文件
     * @return
     * @throws IOException
     */
    @PostMapping("/upload")
    public String upload(@RequestParam MultipartFile file) throws IOException {
        String originalFilename = file.getOriginalFilename();
        String type = FileUtil.extName(originalFilename); // 文件类型
        long size = file.getSize()/1024;
//        // 存储到磁盘
//        IFile uploadParenFile = new IFile(fileUploadPath);
//        // 判断文件目录是否存在
//        if (!uploadParenFile.exists()){
//            uploadParenFile.mkdirs();
//        }
        // 定义一个文件唯一识别码
        String uuid = IdUtil.fastSimpleUUID();
        String fileUUID = uuid + StrUtil.DOT+type;
        File uploadFile = new File(fileUploadPath + fileUUID);

        // 判断父级目录
        if(!uploadFile.getParentFile().exists()){
            uploadFile.getParentFile().mkdirs();
        }
        // 当文件存在时获取文件的MD5
        String md5;
        String url;
        // 上传文件到磁盘
        file.transferTo(uploadFile);
        // 获取文件的MD5
        md5 = SecureUtil.md5(uploadFile);
        // 对比数据库是否有相同的记录
        IFile file1 = getFileMd5(md5);

        // 获取文件的url
        if (file1!=null){
            url = file1.getUrl();
            // 由于文件已存在，删除刚上传的文件
            uploadFile.delete();
        }else {
            // 把获取到的文件存储到磁盘目录
            url = "http://localhost:9911/file/"+fileUUID;
        }

//        if (uploadFile.exists()){
//            //
//            md5 = SecureUtil.md5(uploadFile);
//            // 对比数据库是否有相同的记录
//            com.zspringboot.demo.entity.IFile file1 = getFileMd5(md5);
//
//            // 获取文件的url
//            if (file1!=null){
//                url = file1.getUrl();
//            }else {
//                // 把获取到的文件存储到磁盘目录
//                file.transferTo(uploadFile);
//                url = "http://localhost:9911/file/"+fileUUID;
//            }
//        }else {
//            file.transferTo(uploadFile);
//            md5 = SecureUtil.md5(uploadFile);
//            url = "http://localhost:9911/file/"+fileUUID;
//        }




        // 存储数据库
        IFile saveFile = new IFile();
        saveFile.setName(originalFilename);
        saveFile.setType(type);
        saveFile.setSize(size);
        saveFile.setUrl(url);
        saveFile.setMd5(md5);
        fileMapper.insert(saveFile);
        return url;
    }

    @GetMapping("{fileUUID}")
    public void downLoad(@PathVariable String fileUUID, HttpServletResponse response) throws IOException {
        // 根据文件的唯一标识码获取文件
        File uploadFile = new File(fileUploadPath+fileUUID);
        // 设置输出流的格式
        ServletOutputStream os = response.getOutputStream();
        response.addHeader("Content-Disposition","attachment;filename"+ URLEncoder.encode(fileUUID,"UTF-8"));
        response.setContentType("application/octet-stream");

        // 读取上传文件的字节流
        os.write(FileUtil.readBytes(uploadFile));
        os.flush();
        os.close();
    }

    private IFile getFileMd5(String md5){
        // 查询文件是否存在
        QueryWrapper<IFile> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("md5",md5);
        List<IFile> fileList = fileMapper.selectList(queryWrapper);
        return fileList.size()==0?null:fileList.get(0);
    }
    // 更新
    @PostMapping("/update")
    public Result update(@RequestBody IFile f) {
        return Result.success( fileMapper.updateById(f));
    }
    // 删除
    @DeleteMapping("/{id}")
    public Result delete(@PathVariable Integer id) {
        IFile file0 = fileMapper.selectById(id);
        file0.setIsDelete(true);
        fileMapper.updateById(file0);
        return Result.success();
    }
    // 批量删除
    @PostMapping("/del/batch")
    public Result deleteBacth(@RequestBody List<Integer> ids){
        QueryWrapper<IFile> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("id",ids);
        List<IFile> files = fileMapper.selectList(queryWrapper);
        for (IFile f:files){
            f.setIsDelete(true);
            fileMapper.updateById(f);
        }

        return Result.success();
    }
    // 查询所有数据
    /**
     * 分页查询接口
     * @param pageNum
     * @param pageSize
     * @param name
     * @return
     */
    @GetMapping("/page")
    public Result findPage(@RequestParam Integer pageNum,
                           @RequestParam Integer pageSize,
                           @RequestParam(defaultValue = "") String name) {
        QueryWrapper<IFile> queryWrapper = new QueryWrapper<>();
        // 查询未删除的记录
        queryWrapper.eq("is_delete",false);
        queryWrapper.orderByDesc("id");
        if (!"".equals(name))
            queryWrapper.like("name",name);

//        queryWrapper.or().like("address",address);   or
        queryWrapper.orderByDesc("id");
        return Result.success(fileMapper.selectPage(new Page<>(pageNum, pageSize),queryWrapper));
    }
}
